/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
	"fmt"
	"fullerene/service"
	"log"

	"github.com/spf13/cobra"
)

// serviceCmd represents the service command
var serviceCmd = &cobra.Command{
	Use:   "service",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: runService,
}

var serviceCfg service.Options

func init() {
	log.SetFlags(log.LstdFlags | log.Llongfile)
	rootCmd.AddCommand(serviceCmd)
	cobra.OnInitialize(loadConfig)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// serviceCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// serviceCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
	f := serviceCmd.Flags()
	f.IntVarP(&serviceCfg.Port, "port", "p", 8888, "listen port")
	f.DurationVarP(&serviceCfg.LoginTimeout, "login-timeout", "l", 10, "login timeout")
	f.DurationVarP(&serviceCfg.PingPongInterval, "ping-pong-interval", "i", 10, "ping pong interval")
	f.DurationVarP(&serviceCfg.HandlerTimeout, "handler-timeout", "t", 10, "handler timeout")
}

func loadConfig() {
	fmt.Println("load config")
	//TODO
}

func authProvider(user, pass string) error {
	fmt.Println("authProvider:", user, pass)
	return nil
}

func runService(cmd *cobra.Command, args []string) {
	fmt.Println("service started at port:", serviceCfg.Port)
	engine := service.New(&serviceCfg, service.WithAuthProvider(authProvider))

	engine.AddHandler(service.ChatText, func(c *service.Context) error {
		var msg string
		if err := c.Bind(&msg); err != nil {
			return err
		}

		log.Println("chat text:", msg)

		reply := service.NewMessage().SetType(service.ChatText).SetPayload(msg)
		data, err := reply.Bytes()
		if err != nil {
			return err
		}
		_, err = c.Write(data)
		if err != nil {
			return err
		}
		return nil
	})
	if err := engine.Run(); err != nil {
		log.Fatal(err)
	}
}
